// Copyright 2020 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------
// Modification history:
// feature: listener code decoupling
// feature: support agent between domain
// feature: provide query interfaces
// feature: discovery support client and server
// ------------------------------------------------------------------

#ifndef EDPSERVERLISTENER2_H_
#define EDPSERVERLISTENER2_H_
#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC

#include <discovery/endpoint/EDPSimpleListeners.h>
#include <xmlparser/qos/XMLReaderQos.hpp>
#include <xmlparser/qos/XMLWriterQos.hpp>

namespace evbs {
namespace ertps {
namespace rtps {

class RTPSReader;
// class BaseReader;
class PDPServer;
class EDPServer;
using vbs::common::CacheChange_t;
/*!
 * Class EDPServerPUBListener, used to define the behavior when a new WriterProxyData is received.
 * @ingroup DISCOVERY_MODULE
 */
class EDPServerPUBListener : public EDPBasePUBListener {
 public:
    /*!
       Constructor
     * @param sedp Pointer to the EDPServer associated with this listener.
     */
    EDPServerPUBListener(EDPServer* sedp);

    virtual ~EDPServerPUBListener() {}

    //! return the PDPServer
    PDPServer* get_pdp();

    /**
     * Virtual method,
     * @param reader
     * @param change
     */
    void onNewCacheChangeAdded(vbs::dispatcher::SubstrateReader* sub_reader,
                               const CacheChange_t* const change) override;

 private:
    bool get_writer_proxy_topic_name(GUID_t auxGUID, std::string& topic_name, std::string& type_name);

    void notify_discoverydatabase(std::string topic_name, std::string type_name, RTPSReader* reader,
                                  CacheChange_t* change, const vbsutil::xmlparser::WriterQos& qos,
                                  bool take_locator = false);

    void continue_with_writer(RTPSReader* reader, CacheChange_t* change, vbsutil::xmlparser::WriterQos& qos,
                              bool take_locator);

    //! Pointer to the EDPServer
    EDPServer* sedp_;
};

/*!
 * Class EDPServerSUBListener, used to define the behavior when a new ReaderProxyData is received.
 * @ingroup DISCOVERY_MODULE
 */
class EDPServerSUBListener : public EDPBaseSUBListener {
 public:
    /*!
       Constructor
     * @param sedp Pointer to the EDPServer associated with this listener.
     */
    EDPServerSUBListener(EDPServer* sedp);

    virtual ~EDPServerSUBListener() = default;

    //! return the PDPServer
    PDPServer* get_pdp();

    /**
     * @param reader
     * @param change
     */
    void onNewCacheChangeAdded(vbs::dispatcher::SubstrateReader* sub_reader,
                               const CacheChange_t* const change) override;

 private:
    bool get_reader_proxy_topic_name(GUID_t auxGUID, std::string& topic_name, std::string& type_name);

    void notify_discoverydatabase(std::string topic_name, std::string type_name, RTPSReader* reader,
                                  CacheChange_t* change, const vbsutil::xmlparser::ReaderQos& qos,
                                  bool take_locator = false, uint32_t queue_id = 0);

    void continue_with_reader(RTPSReader* reader, CacheChange_t* change, vbsutil::xmlparser::ReaderQos& qos,
                              bool take_locator, uint32_t queue_id);

    //! Pointer to the EDPServer
    EDPServer* sedp_;
};

} /* namespace rtps */
}  // namespace ertps
} /* namespace evbs */
#endif  // ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
#endif  /* EDPSERVERLISTENER2_H_ */
